using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using InterfaceWeaver.AopCore;
using Roslyn.Compilers.CSharp;

namespace InterfaceWeaver.CustomTool
{
    public class MapDefaultInstanceAspectHandler : AspectHandlerBase<MapDefaultInstanceAttribute>
    {

        /// <summary>
        /// Determines whether the aspect is known and could be handled by aspect handler.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <returns></returns>
        public override bool HandleOnInterfacePreview(AspectDispatcher context, AttributeSyntax attributeSyntax)
        {
            return base.HandleOnInterfacePreview(context, attributeSyntax);
        }

        /// <summary>
        /// Regarding all the handler answering preview step, this step determines whether there are some aspect handler that should be removed from next live cycle.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="indirectAspectHandler"> </param>
        /// <param name="indirectAttributeSyntax"> </param>
        /// <returns></returns>
        public override bool IsIndirectAspectsCompliantOnInterface(AspectDispatcher context, AttributeSyntax attributeSyntax, IAspectHandler indirectAspectHandler, AttributeSyntax indirectAttributeSyntax)
        {
            return !(indirectAspectHandler is MapDependencyPropertyAspectHandler);
        }

        /// <summary>
        /// Regarding all the handler answering preview step, this step determines whether there are some aspect handler that should be removed from next live cycle.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="indirectAspectHandler"> </param>
        /// <param name="indirectAttributeSyntax"> </param>
        /// <returns></returns>
        public override bool IsIndirectAspectsCompliantOnProperty(AspectDispatcher context, AttributeSyntax attributeSyntax, IAspectHandler indirectAspectHandler, AttributeSyntax indirectAttributeSyntax)
        {
            return !(indirectAspectHandler is MapDependencyPropertyAspectHandler);
        }

        /// <summary>
        /// Handles the on member.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="attributeSyntax">The attribute syntax.</param>
        /// <param name="propertyDeclarationSyntax"> </param>
        /// <param name="handlerStreams"> </param>
        /// <returns>
        /// True if the aspect is handled, false otherwise
        /// </returns>
        public override void HandleOnProperty(AspectDispatcher context, AttributeSyntax attributeSyntax, PropertyDeclarationSyntax propertyDeclarationSyntax, IDictionary<PropertyDeclarationSyntax, AspectTuple[]> handlerStreams)
        {
            var currentField = context.WeavedCodeContext.CurrentCodeMemberPropertyDeclaration.CurrentCodeMemberFieldDeclaration;
            currentField.InitExpression = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(
                    new CodeTypeReferenceExpression(
                           typeof(Activator)),
                           "CreateInstance",
                           currentField.Type));
        }
    }
}